package com.eclipse.organigram.views;

import java.io.File;

import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;

import com.eclipse.organigram.Activator;
import com.eclipse.organigram.model.OrganigramModel;
import com.eclipse.organigram.preferences.PreferenceConstants;
import com.eclipse.organigram.views.ui.ErrorComposite;
import com.eclipse.organigram.views.ui.InfoComposite;
import com.eclipse.organigram.views.ui.OrganigramComposite;
import com.fasterxml.jackson.databind.ObjectMapper;

public class OrganigramView extends ViewPart {

	public static final String ID = "com.eclipse.organigram.views.OrganigramView";

	private Composite composite;

	private Composite parent;

	@Override
	public void init(IViewSite site) throws PartInitException {
		super.init(site);
		Activator.getDefault().getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() {
			@Override
			public void propertyChange(PropertyChangeEvent event) {
				if (PreferenceConstants.ORGANIGRAM_JSON_PATH.equals(event.getProperty())) {
					Composite parent = composite.getParent();
					composite.dispose();
					composite = configureComposite(parent);
					parent.layout(true);
				}
			}
		});
	}
	
	public void createPartControl(Composite parent) {
		this.parent = parent;
		composite = configureComposite(parent);
	}

	private Composite configureComposite(Composite parent) {
		File jsonFile;
		String jsonPath = Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.ORGANIGRAM_JSON_PATH);
		if (jsonPath == null || jsonPath.trim().isEmpty()) {
			return new InfoComposite(parent, "INFO: Your organigram is not yet confiugred. Please visit Eclipse preferences.");
		} else {
			jsonFile = new File(jsonPath);
			if (! jsonFile.exists()) {
				return new InfoComposite(parent, "INFO: Configured organigram does not exist. Please visit Eclipse preferences page.");
			}
		}
		try {
			return new OrganigramComposite(parent, createOrganigramModel(jsonFile));
		} catch (Exception e) {
			return new ErrorComposite(parent, e);
		}
	}

	private OrganigramModel createOrganigramModel(File jsonFile) {
		ObjectMapper mapper = new ObjectMapper();
		try {
			return mapper.readValue(jsonFile, OrganigramModel.class);
		} catch (Exception e) {
			throw new RuntimeException("Error in JSON syntax while binding JSON to Java POJOs. \nCheck your JSON organigram and try again.", e);
		}
	}

	public void setFocus() {
		composite.setFocus();
	}

	public void collapse() {
		if (composite instanceof OrganigramComposite) {
			((OrganigramComposite) composite).collapse();
		}
	}

	public void expand() {
		if (composite instanceof OrganigramComposite) {
			((OrganigramComposite) composite).expand();
		}
	}

	public void refresh() {
		composite.dispose();
		composite = configureComposite(parent);
		parent.layout();
	}
	
}